var_x <- 1:10
var_y <- 11:20

plot(var_x, var_y)


rand_sample <- sample(var_x, size = 100, replace = TRUE)
hist(rand_sample)

Grammar Of Graphics

  • data
  • aesthetic mapping
  • geometric object
  • statistical transformations
  • scales
  • coordinate system
  • position adjustments
  • faceting

Load package and data

library(tidyverse)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
── Attaching packages ─────────────────────────────── tidyverse 1.2.1 ──
✔ ggplot2 3.2.1     ✔ purrr   0.3.2
✔ tibble  2.1.3     ✔ dplyr   0.8.3
✔ tidyr   0.8.3     ✔ stringr 1.4.0
✔ readr   1.3.1     ✔ forcats 0.4.0
── Conflicts ────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
data <- read_csv("plot_data.csv")
Parsed with column specification:
cols(
  Gene = col_character(),
  Length = col_double(),
  RPF = col_double(),
  mRNA = col_double(),
  uATG = col_logical(),
  Chromosome = col_character(),
  Size = col_double()
)
data

Structure of ggplot

Simple scatterplot

my_plot + 
  geom_point()

Changing scales of axes

my_plot +
  geom_point() +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10")


my_plot +
  geom_point() +
  scale_x_continuous(trans = "log2") +
  scale_y_continuous(trans = "log10")


my_plot +
  geom_point() +
  scale_x_continuous(trans = "log2")

Specify axis breakpoints

my_plot +
  geom_point() +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000))

Change limits and label styles of plots

my_plot +
  geom_point() +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000),
                     labels = scales::comma) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000),
                     labels = scales::comma)


my_plot +
  geom_point() +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000),
                     labels = scales::comma,
                     limits = c(1000, 25000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000),
                     labels = scales::comma,
                     limits = c(1000, 25000))


my_plot +
  geom_point() +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 25000),
                     labels = scales::comma,
                     limits = c(1000, 25000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 25000),
                     labels = scales::comma,
                     limits = c(1000, 25000))

Axis labels

my_plot +
  geom_point() +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot")

Changing transparency of points

my_plot +
  geom_point(alpha = 0.1) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot")

Color points

Color points with a variables (aesthetic mapping) - continuous scale

ggplot(data = data, aes(x = mRNA, y = RPF, color = Chromosome)) +
  geom_point(alpha = 0.4) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot")


ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot")

Color points with a variables (aesthetic mapping) - discrete scale and color brewer

ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  scale_color_brewer(palette = "Set1")

Change shapes of points

ggplot(data = data, aes(x = mRNA, y = RPF, shape = uATG, color = uATG)) +
  geom_point(alpha = 0.4) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  scale_color_brewer(palette = "Set1")

Change sizes of points

ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  scale_color_brewer(palette = "Set1")


ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG, size = Size)) +
  geom_point(alpha = 0.4) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  scale_color_brewer(palette = "Set1")


ggplot(data = data, aes(x = mRNA, y = RPF, color = Size, shape = uATG)) +
  geom_point(alpha = 0.4) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  scale_color_gradient(low = "red", high = "blue")

Adding trendlines and regression lines

Statistical tests

library(ggpubr)
Loading required package: magrittr

Attaching package: ‘magrittr’

The following object is masked from ‘package:purrr’:

    set_names

The following object is masked from ‘package:tidyr’:

    extract
ggplot(data = data, aes(x = mRNA, y = RPF)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  stat_cor() + 
  geom_smooth(method = "lm")


ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  scale_color_brewer(palette = "Set1") +
  stat_cor() +
  geom_smooth(method = "lm")



ggplot(data = data, aes(x = mRNA, y = RPF, color = Chromosome)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  stat_cor() +
  geom_smooth(method = "lm")

Separate panels

ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  stat_cor() +
  geom_smooth(method = "lm") +
  facet_grid(.~uATG)


ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  stat_cor() +
  geom_smooth(method = "lm") +
  facet_grid(uATG~.)


ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  stat_cor() +
  geom_smooth(method = "lm") +
  facet_grid(.~Chromosome)


ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  stat_cor() +
  geom_smooth(method = "lm") +
  facet_wrap(.~Chromosome)

Histograms

ggplot(data = data, aes(x = mRNA)) +
  geom_histogram() +
  scale_x_continuous(trans = "log10") +
  labs(x = "Yeast mRNA abundance", 
       y = "Frequency", 
       title = "Histogram")


ggplot(data = data, aes(x = mRNA)) +
  geom_histogram(bins = 100) +
  scale_x_continuous(trans = "log10") +
  labs(x = "Yeast mRNA abundance", 
       y = "Frequency", 
       title = "Histogram")


ggplot(data = data, aes(x = mRNA, color = uATG)) +
  geom_histogram(bins = 100) +
  scale_x_continuous(trans = "log10") +
  labs(x = "Yeast mRNA abundance", 
       y = "Frequency", 
       title = "Histogram")


ggplot(data = data, aes(x = mRNA, color = uATG)) +
  geom_histogram(bins = 100, position = "dodge") +
  scale_x_continuous(trans = "log10") +
  labs(x = "Yeast mRNA abundance", 
       y = "Frequency", 
       title = "Histogram")

Density plots

ggplot(data = data, aes(x = mRNA, fill = uATG)) +
  geom_density(alpha = 0.5) +
  scale_x_continuous(trans = "log10") +
  labs(x = "Yeast mRNA abundance", 
       y = "Frequency", 
       title = "Density plot") +
  scale_fill_brewer(palette = "Set1")

Multi-panel density plots

ggplot(data = data, aes(x = mRNA, fill = uATG)) +
  geom_density(alpha = 0.5) +
  scale_x_continuous(trans = "log10") +
  labs(x = "Yeast mRNA abundance", 
       y = "Frequency", 
       title = "Density plot") +
  scale_fill_brewer(palette = "Set1") +
  facet_wrap(~Chromosome)

Boxplots and Violin plots

ggplot(data = data, aes(x = uATG, y = mRNA, fill = uATG)) +
  geom_boxplot() +
  scale_y_continuous(trans = "log10") +
  labs(x = "uATGs", 
       y = "Yeast mRNA abundance", 
       title = "Boxplot") +
  scale_fill_brewer(palette = "Set1")


ggplot(data = data, aes(x = uATG, y = mRNA, fill = uATG)) +
  geom_boxplot() +
  scale_y_continuous(trans = "log10") +
  labs(x = "uATGs", 
       y = "Yeast mRNA abundance", 
       title = "Boxplot") +
  scale_fill_brewer(palette = "Set1") +
  stat_compare_means(method = "t.test")

my_comparisons <- list(c("Chr-1", "Chr-2"),
                       c("Chr-1", "Chr-9"))

ggplot(data = data, aes(x = Chromosome, y = mRNA, fill = Chromosome)) +
  geom_boxplot() +
  scale_y_continuous(trans = "log10") +
  labs(x = "uATGs", 
       y = "Yeast mRNA abundance", 
       title = "Boxplot") +
  stat_compare_means(comparisons = my_comparisons, method = "t.test")

my_comparisons <- list(c("Chr-1", "Chr-2"),
                       c("Chr-1", "Chr-9"))

ggplot(data = data, aes(x = Chromosome, y = mRNA, fill = Chromosome)) +
  geom_violin() +
  scale_y_continuous(trans = "log10") +
  labs(x = "uATGs", 
       y = "Yeast mRNA abundance", 
       title = "Violin plot") +
  stat_compare_means(comparisons = my_comparisons, method = "t.test")

Boxplots with scatter points

ggplot(data = data, aes(x = uATG, y = mRNA, fill = uATG)) +
  geom_boxplot() +
  scale_y_continuous(trans = "log10") +
  labs(x = "uATGs", 
       y = "Yeast mRNA abundance", 
       title = "Boxplot") +
  scale_fill_brewer(palette = "Set1") +
  stat_compare_means(method = "t.test") +
  geom_jitter(alpha = 0.3, width = 0.1, height = 0)

Saving plots

myboxplot <- ggplot(data = data, aes(x = uATG, y = mRNA, fill = uATG)) +
  geom_boxplot() +
  scale_y_continuous(trans = "log10") +
  labs(x = "uATGs", 
       y = "Yeast mRNA abundance", 
       title = "Boxplot") +
  scale_fill_brewer(palette = "Set1") +
  stat_compare_means(method = "t.test") +
  geom_jitter(alpha = 0.3, width = 0.1, height = 0)
ggsave(myboxplot, filename = "myboxplot.png")
Saving 7 x 7 in image

Interactive plots

myscatterplot <- ggplot(data = data, aes(x = mRNA, y = RPF, color = uATG, label = Gene)) +
  geom_point(alpha = 0.4, 
             size = 2) +
  scale_x_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  scale_y_continuous(trans = "log10",
                     breaks = c(1, 5, 10, 50, 100, 500, 1000, 5000, 10000)) +
  labs(x = "Yeast mRNA abundance", 
       y = "Yeast RPF abundance", 
       title = "Scatterplot") +
  scale_color_brewer(palette = "Set1") +
  stat_cor() +
  geom_smooth(method = "lm")
library(plotly)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout
ggplotly(myscatterplot)

Themes

myscatterplot +
  theme_pubr()

LS0tCnRpdGxlOiAiTGFiIDEwIC0gZ2dwbG90IgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogICAgdG9jX2Zsb2F0OiBUUlVFCi0tLQoKYGBge3J9CnZhcl94IDwtIDE6MTAKdmFyX3kgPC0gMTE6MjAKCnBsb3QodmFyX3gsIHZhcl95KQoKcmFuZF9zYW1wbGUgPC0gc2FtcGxlKHZhcl94LCBzaXplID0gMTAwLCByZXBsYWNlID0gVFJVRSkKaGlzdChyYW5kX3NhbXBsZSkKYGBgCgoKIyMjIEdyYW1tYXIgT2YgR3JhcGhpY3MKLSBkYXRhCi0gYWVzdGhldGljIG1hcHBpbmcKLSBnZW9tZXRyaWMgb2JqZWN0Ci0gc3RhdGlzdGljYWwgdHJhbnNmb3JtYXRpb25zCi0gc2NhbGVzCi0gY29vcmRpbmF0ZSBzeXN0ZW0KLSBwb3NpdGlvbiBhZGp1c3RtZW50cwotIGZhY2V0aW5nCgojIyMgTG9hZCBwYWNrYWdlIGFuZCBkYXRhCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCmBgYHtyfQpkYXRhIDwtIHJlYWRfY3N2KCJwbG90X2RhdGEuY3N2IikKZGF0YQpgYGAKCiMjIyBTdHJ1Y3R1cmUgb2YgZ2dwbG90CmBgYHtyfQpteV9wbG90IDwtIGdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGKSkKbXlfcGxvdApgYGAKCiMjIyBTaW1wbGUgc2NhdHRlcnBsb3QKYGBge3J9Cm15X3Bsb3QgKyAKICBnZW9tX3BvaW50KCkKYGBgCgoKIyMjIENoYW5naW5nIHNjYWxlcyBvZiBheGVzCmBgYHtyfQpteV9wbG90ICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiKQoKbXlfcGxvdCArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiKQoKbXlfcGxvdCArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMiIpCmBgYAoKCiMjIyBTcGVjaWZ5IGF4aXMgYnJlYWtwb2ludHMKYGBge3J9Cm15X3Bsb3QgKwogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkKCmBgYAoKCgojIyMgQ2hhbmdlIGxpbWl0cyBhbmQgbGFiZWwgc3R5bGVzIG9mIHBsb3RzCmBgYHtyfQpteV9wbG90ICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCksCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHNjYWxlczo6Y29tbWEpCgpteV9wbG90ICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OmNvbW1hLAogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDEwMDAsIDI1MDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OmNvbW1hLAogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDEwMDAsIDI1MDAwKSkKCm15X3Bsb3QgKwogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCwgMjUwMDApLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OmNvbW1hLAogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDEwMDAsIDI1MDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDAsIDI1MDAwKSwKICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gc2NhbGVzOjpjb21tYSwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygxMDAwLCAyNTAwMCkpCmBgYAoKIyMjIEF4aXMgbGFiZWxzCmBgYHtyfQpteV9wbG90ICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBsYWJzKHggPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHkgPSAiWWVhc3QgUlBGIGFidW5kYW5jZSIsIAogICAgICAgdGl0bGUgPSAiU2NhdHRlcnBsb3QiKQpgYGAKCgojIyMgQ2hhbmdpbmcgdHJhbnNwYXJlbmN5IG9mIHBvaW50cwpgYGB7cn0KbXlfcGxvdCArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBsYWJzKHggPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHkgPSAiWWVhc3QgUlBGIGFidW5kYW5jZSIsIAogICAgICAgdGl0bGUgPSAiU2NhdHRlcnBsb3QiKQpgYGAKCgojIyMgQ29sb3IgcG9pbnRzCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSwgeSA9IFJQRikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4xLAogICAgICAgICAgICAgY29sb3IgPSAiYmx1ZSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikKYGBgCgoKIyMjIENvbG9yIHBvaW50cyB3aXRoIGEgdmFyaWFibGVzIChhZXN0aGV0aWMgbWFwcGluZykgLSBjb250aW51b3VzIHNjYWxlCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSwgeSA9IFJQRiwgY29sb3IgPSBDaHJvbW9zb21lKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikKCmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGLCBjb2xvciA9IHVBVEcpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBsYWJzKHggPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHkgPSAiWWVhc3QgUlBGIGFidW5kYW5jZSIsIAogICAgICAgdGl0bGUgPSAiU2NhdHRlcnBsb3QiKQpgYGAKCgojIyMgQ29sb3IgcG9pbnRzIHdpdGggYSB2YXJpYWJsZXMgKGFlc3RoZXRpYyBtYXBwaW5nKSAtIGRpc2NyZXRlIHNjYWxlIGFuZCBjb2xvciBicmV3ZXIKYGBge3J9CmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGLCBjb2xvciA9IHVBVEcpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBsYWJzKHggPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHkgPSAiWWVhc3QgUlBGIGFidW5kYW5jZSIsIAogICAgICAgdGl0bGUgPSAiU2NhdHRlcnBsb3QiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpgYGAKCiMjIyBDaGFuZ2Ugc2hhcGVzIG9mIHBvaW50cwpgYGB7cn0KZ2dwbG90KGRhdGEgPSBkYXRhLCBhZXMoeCA9IG1STkEsIHkgPSBSUEYsIHNoYXBlID0gdUFURywgY29sb3IgPSB1QVRHKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQpgYGAKCgojIyMgQ2hhbmdlIHNpemVzIG9mIHBvaW50cwpgYGB7cn0KZ2dwbG90KGRhdGEgPSBkYXRhLCBhZXMoeCA9IG1STkEsIHkgPSBSUEYsIGNvbG9yID0gdUFURykpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC40LCAKICAgICAgICAgICAgIHNpemUgPSAyKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIGxhYnMoeCA9ICJZZWFzdCBtUk5BIGFidW5kYW5jZSIsIAogICAgICAgeSA9ICJZZWFzdCBSUEYgYWJ1bmRhbmNlIiwgCiAgICAgICB0aXRsZSA9ICJTY2F0dGVycGxvdCIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGLCBjb2xvciA9IHVBVEcsIHNpemUgPSBTaXplKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZ2dwbG90KGRhdGEgPSBkYXRhLCBhZXMoeCA9IG1STkEsIHkgPSBSUEYsIGNvbG9yID0gU2l6ZSwgc2hhcGUgPSB1QVRHKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdyA9ICJyZWQiLCBoaWdoID0gImJsdWUiKQpgYGAKCgojIyMgQWRkaW5nIHRyZW5kbGluZXMgYW5kIHJlZ3Jlc3Npb24gbGluZXMKYGBge3J9CmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQsIAogICAgICAgICAgICAgc2l6ZSA9IDIpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsCiAgICAgICAgICAgICAgY29sb3IgPSAicmVkIikKYGBgCgoKIyMjIFN0YXRpc3RpY2FsIHRlc3RzCmBgYHtyfQpsaWJyYXJ5KGdncHVicikKYGBgCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSwgeSA9IFJQRikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC40LCAKICAgICAgICAgICAgIHNpemUgPSAyKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIGxhYnMoeCA9ICJZZWFzdCBtUk5BIGFidW5kYW5jZSIsIAogICAgICAgeSA9ICJZZWFzdCBSUEYgYWJ1bmRhbmNlIiwgCiAgICAgICB0aXRsZSA9ICJTY2F0dGVycGxvdCIpICsKICBzdGF0X2NvcigpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKCmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGLCBjb2xvciA9IHVBVEcpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgCiAgICAgICAgICAgICBzaXplID0gMikgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBsYWJzKHggPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHkgPSAiWWVhc3QgUlBGIGFidW5kYW5jZSIsIAogICAgICAgdGl0bGUgPSAiU2NhdHRlcnBsb3QiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICBzdGF0X2NvcigpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKQoKCmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGLCBjb2xvciA9IENocm9tb3NvbWUpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgCiAgICAgICAgICAgICBzaXplID0gMikgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBsYWJzKHggPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHkgPSAiWWVhc3QgUlBGIGFidW5kYW5jZSIsIAogICAgICAgdGl0bGUgPSAiU2NhdHRlcnBsb3QiKSArCiAgc3RhdF9jb3IoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKYGBgCgojIyMgU2VwYXJhdGUgcGFuZWxzCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSwgeSA9IFJQRiwgY29sb3IgPSB1QVRHKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQsIAogICAgICAgICAgICAgc2l6ZSA9IDIpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikgKwogIHN0YXRfY29yKCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsKICBmYWNldF9ncmlkKC5+dUFURykKCmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCB5ID0gUlBGLCBjb2xvciA9IHVBVEcpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgCiAgICAgICAgICAgICBzaXplID0gMikgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBsYWJzKHggPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHkgPSAiWWVhc3QgUlBGIGFidW5kYW5jZSIsIAogICAgICAgdGl0bGUgPSAiU2NhdHRlcnBsb3QiKSArCiAgc3RhdF9jb3IoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogIGZhY2V0X2dyaWQodUFUR34uKQoKZ2dwbG90KGRhdGEgPSBkYXRhLCBhZXMoeCA9IG1STkEsIHkgPSBSUEYsIGNvbG9yID0gdUFURykpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC40LCAKICAgICAgICAgICAgIHNpemUgPSAyKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygxLCA1LCAxMCwgNTAsIDEwMCwgNTAwLCAxMDAwLCA1MDAwLCAxMDAwMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIGxhYnMoeCA9ICJZZWFzdCBtUk5BIGFidW5kYW5jZSIsIAogICAgICAgeSA9ICJZZWFzdCBSUEYgYWJ1bmRhbmNlIiwgCiAgICAgICB0aXRsZSA9ICJTY2F0dGVycGxvdCIpICsKICBzdGF0X2NvcigpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArCiAgZmFjZXRfZ3JpZCgufkNocm9tb3NvbWUpCgpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSwgeSA9IFJQRiwgY29sb3IgPSB1QVRHKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQsIAogICAgICAgICAgICAgc2l6ZSA9IDIpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikgKwogIHN0YXRfY29yKCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsKICBmYWNldF93cmFwKC5+Q2hyb21vc29tZSkKYGBgCgojIyMgSGlzdG9ncmFtcwpgYGB7cn0KZ2dwbG90KGRhdGEgPSBkYXRhLCBhZXMoeCA9IG1STkEpKSArCiAgZ2VvbV9oaXN0b2dyYW0oKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIikgKwogIGxhYnMoeCA9ICJZZWFzdCBtUk5BIGFidW5kYW5jZSIsIAogICAgICAgeSA9ICJGcmVxdWVuY3kiLCAKICAgICAgIHRpdGxlID0gIkhpc3RvZ3JhbSIpCgpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAwKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIikgKwogIGxhYnMoeCA9ICJZZWFzdCBtUk5BIGFidW5kYW5jZSIsIAogICAgICAgeSA9ICJGcmVxdWVuY3kiLCAKICAgICAgIHRpdGxlID0gIkhpc3RvZ3JhbSIpCgpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSwgY29sb3IgPSB1QVRHKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMDApICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIsIAogICAgICAgdGl0bGUgPSAiSGlzdG9ncmFtIikKCmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCBjb2xvciA9IHVBVEcpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwMCwgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIikgKwogIGxhYnMoeCA9ICJZZWFzdCBtUk5BIGFidW5kYW5jZSIsIAogICAgICAgeSA9ICJGcmVxdWVuY3kiLCAKICAgICAgIHRpdGxlID0gIkhpc3RvZ3JhbSIpCmBgYAoKCiMjIyBEZW5zaXR5IHBsb3RzCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gbVJOQSwgZmlsbCA9IHVBVEcpKSArCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIikgKwogIGxhYnMoeCA9ICJZZWFzdCBtUk5BIGFidW5kYW5jZSIsIAogICAgICAgeSA9ICJGcmVxdWVuY3kiLCAKICAgICAgIHRpdGxlID0gIkRlbnNpdHkgcGxvdCIpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQpgYGAKCgoKIyMjIE11bHRpLXBhbmVsIGRlbnNpdHkgcGxvdHMKYGBge3J9CmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBtUk5BLCBmaWxsID0gdUFURykpICsKICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIsIAogICAgICAgdGl0bGUgPSAiRGVuc2l0eSBwbG90IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICBmYWNldF93cmFwKH5DaHJvbW9zb21lKQpgYGAKCgoKIyMjIEJveHBsb3RzIGFuZCBWaW9saW4gcGxvdHMKYGBge3J9CmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSB1QVRHLCB5ID0gbVJOQSwgZmlsbCA9IHVBVEcpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIpICsKICBsYWJzKHggPSAidUFUR3MiLCAKICAgICAgIHkgPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIkJveHBsb3QiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSB1QVRHLCB5ID0gbVJOQSwgZmlsbCA9IHVBVEcpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIpICsKICBsYWJzKHggPSAidUFUR3MiLCAKICAgICAgIHkgPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIkJveHBsb3QiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IikKYGBgCgpgYGB7cn0KbXlfY29tcGFyaXNvbnMgPC0gbGlzdChjKCJDaHItMSIsICJDaHItMiIpLAogICAgICAgICAgICAgICAgICAgICAgIGMoIkNoci0xIiwgIkNoci05IikpCgpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gQ2hyb21vc29tZSwgeSA9IG1STkEsIGZpbGwgPSBDaHJvbW9zb21lKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiKSArCiAgbGFicyh4ID0gInVBVEdzIiwgCiAgICAgICB5ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB0aXRsZSA9ICJCb3hwbG90IikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IG15X2NvbXBhcmlzb25zLCBtZXRob2QgPSAidC50ZXN0IikKYGBgCgpgYGB7cn0KbXlfY29tcGFyaXNvbnMgPC0gbGlzdChjKCJDaHItMSIsICJDaHItMiIpLAogICAgICAgICAgICAgICAgICAgICAgIGMoIkNoci0xIiwgIkNoci05IikpCgpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gQ2hyb21vc29tZSwgeSA9IG1STkEsIGZpbGwgPSBDaHJvbW9zb21lKSkgKwogIGdlb21fdmlvbGluKCkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIpICsKICBsYWJzKHggPSAidUFUR3MiLCAKICAgICAgIHkgPSAiWWVhc3QgbVJOQSBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlZpb2xpbiBwbG90IikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IG15X2NvbXBhcmlzb25zLCBtZXRob2QgPSAidC50ZXN0IikKCmBgYAoKCiMjIyBCb3hwbG90cyB3aXRoIHNjYXR0ZXIgcG9pbnRzCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gdUFURywgeSA9IG1STkEsIGZpbGwgPSB1QVRHKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiKSArCiAgbGFicyh4ID0gInVBVEdzIiwgCiAgICAgICB5ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB0aXRsZSA9ICJCb3hwbG90IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMywgd2lkdGggPSAwLjEsIGhlaWdodCA9IDApCmBgYAoKCiMjIyBTYXZpbmcgcGxvdHMKYGBge3J9Cm15Ym94cGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gdUFURywgeSA9IG1STkEsIGZpbGwgPSB1QVRHKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiKSArCiAgbGFicyh4ID0gInVBVEdzIiwgCiAgICAgICB5ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB0aXRsZSA9ICJCb3hwbG90IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMywgd2lkdGggPSAwLjEsIGhlaWdodCA9IDApCmBgYAoKYGBge3J9Cm15Ym94cGxvdApnZ3NhdmUobXlib3hwbG90LCBmaWxlbmFtZSA9ICJteWJveHBsb3QucG5nIikKYGBgCgojIyMgSW50ZXJhY3RpdmUgcGxvdHMKYGBge3J9Cm15c2NhdHRlcnBsb3QgPC0gZ2dwbG90KGRhdGEgPSBkYXRhLCBhZXMoeCA9IG1STkEsIHkgPSBSUEYsIGNvbG9yID0gdUFURywgbGFiZWwgPSBHZW5lKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQsIAogICAgICAgICAgICAgc2l6ZSA9IDIpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDEsIDUsIDEwLCA1MCwgMTAwLCA1MDAsIDEwMDAsIDUwMDAsIDEwMDAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMCwgNTAwMCwgMTAwMDApKSArCiAgbGFicyh4ID0gIlllYXN0IG1STkEgYWJ1bmRhbmNlIiwgCiAgICAgICB5ID0gIlllYXN0IFJQRiBhYnVuZGFuY2UiLCAKICAgICAgIHRpdGxlID0gIlNjYXR0ZXJwbG90IikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgc3RhdF9jb3IoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKCmBgYAoKYGBge3J9CmxpYnJhcnkocGxvdGx5KQpgYGAKCmBgYHtyfQpnZ3Bsb3RseShteXNjYXR0ZXJwbG90KQpgYGAKCiMjIyBUaGVtZXMKYGBge3J9Cm15c2NhdHRlcnBsb3QgKwogIHRoZW1lX3B1YnIoKQpgYGAKCgoKCgoKCgoKCgoK